const fs = require('fs')
const path = require('path')
const LRU = require('lru-cache')
const express = require('express')
const favicon = require('serve-favicon')
const compression = require('compression')
const bodyParser = require("body-parser")

const resolve = file => path.resolve(__dirname, file)
const { createBundleRenderer } = require('vue-server-renderer')
const axios = require('axios')
const isProd = process.env.NODE_ENV === 'production'
const useMicroCache = process.env.MICRO_CACHE !== 'false'
const serverInfo =
  `express/${require('express/package.json').version} ` +
  `vue-server-renderer/${require('vue-server-renderer/package.json').version}`

const app = express()

axios.defaults.baseURL = 'https://game.qezww.cn/zhs/v1'
axios.defaults.headers = {
    'Content-Type':'application/json',
}
const template = fs.readFileSync(resolve('index.html'), 'utf-8')

function createRenderer (bundle, options) {
  // https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer
  return createBundleRenderer(bundle, Object.assign(options, {
    template,
    // for component caching
    cache: LRU({
      max: 1000,
      maxAge: 1000 * 60 * 15
    }),
    // this is only needed when vue-server-renderer is npm-linked
    basedir: resolve('./dist'),
    // recommended for performance
    runInNewContext: false
  }))
}

let renderer
let readyPromise
if (isProd) {
  // In production: create server renderer using built server bundle.
  // The server bundle is generated by vue-ssr-webpack-plugin.
  const bundle = require('./dist/vue-ssr-server-bundle.json')
  // The client manifests are optional, but it allows the renderer
  // to automatically infer preload/prefetch links and directly add <script>
  // tags for any async chunks used during render, avoiding waterfall requests.
  const clientManifest = require('./dist/vue-ssr-client-manifest.json')
  renderer = createRenderer(bundle, {
    clientManifest
  })
}
else {
  // In development: setup the dev server with watch and hot-reload,
  // and create a new renderer on bundle / index template update.
  readyPromise = require('./build/setup-dev-server')(app, (bundle, options) => {
    renderer = createRenderer(bundle, options)
  })
}

const serve = (path, cache) => express.static(resolve(path), {
  maxAge: cache && isProd ? 1000 * 60 * 60 * 24 * 30 : 0
})

app.use(compression({ threshold: 0 }))
app.use(favicon('./src/assets/logo1.png'))
app.use('/dist', serve('./dist', true))
app.use('/public', serve('./public', true))
// app.use('/manifest.json', serve('./manifest.json', true))
app.use('/service-worker.js', serve('./dist/service-worker.js'))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

// 1-second microcache.
// https://www.nginx.com/blog/benefits-of-microcaching-nginx/
const microCache = LRU({
  max: 100,
  maxAge: 1000
})

// since this app has no user-specific content, every page is micro-cacheable.
// if your app involves user-specific content, you need to implement custom
// logic to determine whether a request is cacheable based on its url and
// headers.
const isCacheable = req => useMicroCache

function render (req, res) {
  const s = Date.now()

  console.log("req.url----",req.url)

  res.setHeader('Content-Type', 'text/html')
  res.setHeader('Server', serverInfo)

  const handleError = err => {
    // if (err && err.code === 404) {
    //   res.status(404).end(error) //'404 | Page Not Found'
    //   // res.writeHead(302,{'Location':"/404.html"});
    // } else {
    //   // Render Error Page or Redirect
    //   res.status(500).end(error) //'500 | Internal Server Error'
    //   console.error(`error during render : ${req.url}`)
    //   console.error(err.stack)
    // }
    var html = fs.readFileSync(resolve('./404.html'), 'utf-8')
    res.end(html); 
  }

  const cacheable = isCacheable(req)
  if (cacheable) {
    const hit = microCache.get(req.url)
    if (hit) {
      if (!isProd) {
        console.log(`cache hit!`)
      }
      return res.end(hit)
    }
  }

  const context = {
    title: '环球加盟', // default title
    description: '环球加盟', 
    url: req.url
  }

  renderer.renderToString(context, (err, html) => {
    if (err) {
      return handleError(err)
    }

    //push head info
    const { title, meta } = context.meta.inject()
    // console.info(787878,context.meta.inject(),555,meta.text())
    var html = html.replace(/<title.*?<\/title>/g, title.text())
    html = html.replace(/<meta.*?name="description".*?\/>/g, meta.text())
    
    res.end(html)
    if (cacheable) {
      microCache.set(req.url, html)
    }
    if (!isProd) {
      console.log(`whole request: ${Date.now() - s}ms`)
    }
  })

}
const baseUrl = 'https://game.qezww.cn/zhs/v1'
// 首页热门列表
app.get('/index/pc/hot', (req, res) => {
  axiosEvent('/index/pc/hot', req, res)
})
// 首页banner list
app.get('/advertisement/pc/index', (req, res) => {
  axiosEvent('/advertisement/pc/index', req, res)
})
// 首页检索信息标签
app.get('/index/pc/searchInfo', (req, res) => {
  axiosEvent('/index/pc/searchInfo', req, res)
})
// 首页检索
app.post('/pc/search', (req, res) => {
  // console.log(999999,req.query.page,req.body)
  _axiosEvent('/pc/search?size=20&page='+req.query.page, req.body, res)
})
// 首页资讯列表
app.get('/consultation/pc/index', (req, res) => {
  axiosEvent('/consultation/pc/index', req, res)
})
// 底部热门标签
app.get('/index/pc/hot/labs', (req, res) => {
  axiosEvent('/index/pc/hot/labs', req, res)
})
// 资讯列表
app.get('/consultation/detail/pc/pages', (req, res) => {
  axiosEvent('/consultation/detail/pc/pages?size=20&page='+req.query.page, req, res)
})
// 资讯相关列表
app.get('/consultation/pc/related/pages', (req, res) => {
  axiosEvent('/consultation/pc/related/pages?size=20&page='+req.query.page, req, res)
})
// 资讯相关列表侧边栏
app.get('/consultation/pc/pages', (req, res) => {
  axiosEvent('/consultation/pc/pages?size=20&page=1', req, res)
})
// 招商详情
app.get('/bizEx/pc/detail', (req, res) => {
  axiosEvent('/bizEx/pc/detail?bizExId='+req.query.bizExId, req, res)
})
// 资讯详情
app.get('/consultation/pc/detail', (req, res) => {
  // console.log(5555,req.query.id)
  axiosEvent('/consultation/pc/detail?id='+req.query.id, req.query.id, res)
})
// 资讯检索
app.get('/consultation/pc/search', (req, res) => {
  // console.log(5555,req.query.id)
  axiosEvent('/consultation/pc/search?id='+req.query.id, req.query.id, res)
})
// 提交手机号
app.get('/bizEx/pc/addConnection', (req, res) => {
  // console.log(5555,req.query.id)
  axiosEvent('/bizEx/pc/addConnection?bizExId='+req.query.bizExId+'&phone='+req.query.phone, req, res)
})
// 友情链接
app.get('/friendShipLink/pc/list', (req, res) => {
  // console.log(5555,req.query.id)
  axiosEvent('/friendShipLink/pc/list', req, res)
})


app.get('*', isProd ? render : (req, res) => {
  readyPromise.then(() => render(req, res))
})

//deal router
// app.use('/', require('./router.js')());

const port = process.env.PORT || 99
app.listen(port, () => {
  console.log(`server started at localhost:${port}`)
})



function axiosEvent(url, params, res){
  axios.get(baseUrl+url)
  .then(function (response) {
    res.json(response.data)//
  })
  .catch(function (error) {
    console.log(error)
  })
}
function _axiosEvent(url, params, res){
  axios.post(baseUrl+url,params)
  .then(function (response) {
    // return response.data
    // console.log(999,response)
    res.json(response.data)//
  })
  .catch(function (error) {
    console.log(error)
  })
}
